package client

import (
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"runtime"
)

var (
	//监听业务端口
	localPort = 9011
	//远程连接端口
	remotePort = 7001
	host       = "127.0.0.1"
)

func Start() {
	var (
		err        error
		remoteConn net.Conn
	)
	address := net.JoinHostPort(host, fmt.Sprintf("%d", remotePort))
	if remoteConn, err = net.Dial("tcp", address); err != nil {
		log.Println("连接远程服务失败")
		os.Exit(1)
	}
	defer remoteConn.Close()

	quit := make(chan int)
	clientRead := make(chan []byte)
	clientWrit := make(chan []byte)

	//bind local
	go localProcess(clientRead, clientWrit, quit)

	go func() {
		for {
			rece := make([]byte, 2048)
			n, e := remoteConn.Read(rece)
			if e != nil && e != io.EOF {
				log.Printf("处理客户端消息失败:%v", e)
				quit <- 1
				runtime.Goexit()
			}

			if n != 0 {
				fmt.Println("客户端收到消息")

				clientRead <- rece[:n]
			}

		}
	}()

	for {
		select {
		case buf := <-clientWrit:
			if _, err = remoteConn.Write(buf); err != nil {
				log.Printf("发送客户端消息失败:%v", err)
				break
			}
		case <-quit:
			break
		}
	}

}

func localProcess(clientRead, clientWrit chan []byte, quit chan int) {
	var (
		localConn net.Conn
		err       error
	)
	if localConn, err = net.Dial("tcp", fmt.Sprintf("%s:%d", host, localPort)); err != nil {
		log.Printf("本地连接失败:%v", err)
		runtime.Goexit()
	}
	defer localConn.Close()
	log.Println("本地连接成功")

	localQuit := make(chan int)

	//receive msg
	go func() {
		for {
			rece := make([]byte, 2048)
			n, e := localConn.Read(rece)
			if e != nil && e != io.EOF {
				log.Printf("处理本地端消息失败:%v", e)
				localQuit <- 1
				runtime.Goexit()
			}
			if n != 0 {
				fmt.Println("本地端收到消息")

				clientWrit <- rece[:n]
			}
		}
	}()

	for {
		select {
		case buf := <-clientRead:
			if _, e := localConn.Write(buf); e != nil {
				log.Printf("发送本地消息失败:%v", e)
				break
			}
		case <-localQuit:
			quit <- 1
			break

		}
	}

}
